package com.xhwl.logistics.controller;

import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.logistics.bo.VehicleParkingLotSecondBO;
import com.xhwl.logistics.bo.input.QueryVehicleAccessRecordStatisticsBO;
import com.xhwl.logistics.bo.input.QueryVehiclePayRecordStatisticsBO;
import com.xhwl.logistics.bo.manipulate.VehicleInitAccessRecordStatisticsBO;
import com.xhwl.logistics.bo.manipulate.VehicleInitPayRecordStatisticsBO;
import com.xhwl.logistics.constant.VehicleConstant;
import com.xhwl.logistics.converter.mapstruct.VehicleInitConverter;
import com.xhwl.logistics.dao.mapper.IVehicleAccessRecordMapper;
import com.xhwl.logistics.dao.mapper.IVehiclePayRecordMapper;
import com.xhwl.logistics.dto.manipulate.VehicleInitStatisticsDTO;
import com.xhwl.logistics.po.VehicleAccessRecordStatisticsDatePO;
import com.xhwl.logistics.po.VehiclePayRecordStatisticsDatePO;
import com.xhwl.logistics.service.IVehicleParkingLotService;
import com.xhwl.logistics.service.cent.IBIVehicleService;
import com.xhwl.logistics.util.AboutDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.util.Optionals;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Slf4j
//@RestController
public class VehicleInitController {

    @Autowired
    private IVehicleParkingLotService vehicleParkingLotService;

    @Autowired
    private IBIVehicleService biVehicleService;

    @Autowired
    private IVehicleAccessRecordMapper vehicleAccessRecordMapper;

    @Autowired
    private IVehiclePayRecordMapper vehiclePayRecordMapper;

    @Autowired
    private VehicleInitConverter vehicleInitConverter;

    //由于初始化功能不对外调用，因此不分层写整个初始化流程逻辑了
    @PostMapping("/init/statistics/access-record")
    public ResultJson<String> initStatisticsForAccessRecord(@RequestBody VehicleInitStatisticsDTO vehicleInitStatisticsDTO) {
        Integer projectId = vehicleInitStatisticsDTO.getProjectId();
        String parkingLotName = vehicleInitStatisticsDTO.getParkingLotName();
        Date startTime = vehicleInitStatisticsDTO.getStartTime();
        Date endTime = vehicleInitStatisticsDTO.getEndTime();
        Date processTime = new Date();

        List<VehicleParkingLotSecondBO> vehicleParkingLotSecondBOList = vehicleParkingLotService.queryParkingLots(projectId, parkingLotName);
        if (vehicleParkingLotSecondBOList.size() != 1) {
            throw new BusinessException("目前仅支持一次初始化一个车场的进出记录统计数据");
        }
        VehicleParkingLotSecondBO vehicleParkingLotSecondBO = vehicleParkingLotSecondBOList.get(0);

        QueryVehicleAccessRecordStatisticsBO queryVehicleAccessRecordStatisticsBO = new QueryVehicleAccessRecordStatisticsBO();
        queryVehicleAccessRecordStatisticsBO.setProjectId(projectId);
        queryVehicleAccessRecordStatisticsBO.setParkId(vehicleParkingLotSecondBO.getParkId());
        queryVehicleAccessRecordStatisticsBO.setDateFormatString("%Y-%m-%d %H");
        queryVehicleAccessRecordStatisticsBO.setStartTime(AboutDateUtil.theSameDayHourOfDate(startTime, VehicleConstant.vehicleTimeZone));
        queryVehicleAccessRecordStatisticsBO.setEndTime(AboutDateUtil.theSameDayHourOfDate(endTime, VehicleConstant.vehicleTimeZone));

        List<VehicleAccessRecordStatisticsDatePO> enterVehicleAccessRecordStatisticsDatePOList = vehicleAccessRecordMapper.enterAccessRecordStatistics(queryVehicleAccessRecordStatisticsBO);
        enterVehicleAccessRecordStatisticsDatePOList.forEach(vehicleAccessRecordStatisticsDatePO -> {
            log.info("enter---------");
            log.info("date: " + vehicleAccessRecordStatisticsDatePO.getDate());
            log.info("count: " + vehicleAccessRecordStatisticsDatePO.getCount());
        });

        List<VehicleAccessRecordStatisticsDatePO> existVehicleAccessRecordStatisticsDatePOList = vehicleAccessRecordMapper.existAccessRecordStatistics(queryVehicleAccessRecordStatisticsBO);
        existVehicleAccessRecordStatisticsDatePOList.forEach(vehicleAccessRecordStatisticsDatePO -> {
            log.info("exit---------");
            log.info("date: " + vehicleAccessRecordStatisticsDatePO.getDate());
            log.info("count: " + vehicleAccessRecordStatisticsDatePO.getCount());
        });

        List<VehicleInitAccessRecordStatisticsBO> vehicleAccessRecordStatisticsBOList = new ArrayList<>();
        for (Date start = startTime; start.before(endTime); start=AboutDateUtil.datePlusHour(start, 1)) {
            VehicleInitAccessRecordStatisticsBO vehicleInitAccessRecordStatisticsBO = new VehicleInitAccessRecordStatisticsBO();
            vehicleInitAccessRecordStatisticsBO.setDate(AboutDateUtil.dateToString(start, "yyyy-MM-dd HH"));
            vehicleInitAccessRecordStatisticsBO.setTotal(0);
            vehicleInitAccessRecordStatisticsBO.setIn(0);
            vehicleInitAccessRecordStatisticsBO.setOut(0);
            vehicleAccessRecordStatisticsBOList.add(vehicleInitAccessRecordStatisticsBO);
        }
        vehicleAccessRecordStatisticsBOList.forEach(vehicleInitAccessRecordStatisticsBO -> {
            log.info("init access record---------");
            log.info("date: " + vehicleInitAccessRecordStatisticsBO.getDate());
        });

        enterVehicleAccessRecordStatisticsDatePOList.forEach(vehicleAccessRecordStatisticsDatePO -> {
            Optional<VehicleInitAccessRecordStatisticsBO> optionalVehicleInitAccessRecordStatisticsBO = vehicleAccessRecordStatisticsBOList.stream()
                    .filter(vehicleInitAccessRecordStatisticsBO -> vehicleInitAccessRecordStatisticsBO.getDate().equals(vehicleAccessRecordStatisticsDatePO.getDate()))
                    .findFirst();

            Optionals.ifPresentOrElse(optionalVehicleInitAccessRecordStatisticsBO, vehicleInitAccessRecordStatisticsBO -> {
                vehicleInitAccessRecordStatisticsBO.setIn(vehicleAccessRecordStatisticsDatePO.getCount());
            }, () -> {
                log.info("在初始化的统计集合中找不到进场该时间:" + vehicleAccessRecordStatisticsDatePO.getDate());
            });
        });
        existVehicleAccessRecordStatisticsDatePOList.forEach(vehicleAccessRecordStatisticsDatePO -> {
            Optional<VehicleInitAccessRecordStatisticsBO> optionalVehicleInitAccessRecordStatisticsBO = vehicleAccessRecordStatisticsBOList.stream()
                    .filter(vehicleInitAccessRecordStatisticsBO -> vehicleInitAccessRecordStatisticsBO.getDate().equals(vehicleAccessRecordStatisticsDatePO.getDate()))
                    .findFirst();

            Optionals.ifPresentOrElse(optionalVehicleInitAccessRecordStatisticsBO, vehicleInitAccessRecordStatisticsBO -> {
                vehicleInitAccessRecordStatisticsBO.setOut(vehicleAccessRecordStatisticsDatePO.getCount());
            }, () -> {
                log.info("在初始化的统计集合中找不到出场该时间:" + vehicleAccessRecordStatisticsDatePO.getDate());
            });
        });
        vehicleAccessRecordStatisticsBOList.forEach(vehicleInitAccessRecordStatisticsBO -> {
            vehicleInitAccessRecordStatisticsBO.setTotal(vehicleInitAccessRecordStatisticsBO.getIn() + vehicleInitAccessRecordStatisticsBO.getOut());
        });

        biVehicleService.addDwsAccessRecordForHours(vehicleInitConverter.toCreateBiVehicleAccessRecordHourFeignDTOList(vehicleAccessRecordStatisticsBOList, projectId, parkingLotName, processTime));

        return ResultJson.successWithResult("init statistics for access record success!");
    }

    @PostMapping("/init/statistics/pay-record")
    public ResultJson<String> initStatisticsForPayRecord(@RequestBody VehicleInitStatisticsDTO vehicleInitStatisticsDTO) {
        Integer projectId = vehicleInitStatisticsDTO.getProjectId();
        String parkingLotName = vehicleInitStatisticsDTO.getParkingLotName();
        Date startTime = vehicleInitStatisticsDTO.getStartTime();
        Date endTime = vehicleInitStatisticsDTO.getEndTime();
        Date processTime = new Date();

        List<VehicleParkingLotSecondBO> vehicleParkingLotSecondBOList = vehicleParkingLotService.queryParkingLots(projectId, parkingLotName);
        if (vehicleParkingLotSecondBOList.size() != 1) {
            throw new BusinessException("目前仅支持一次初始化一个车场的缴费记录统计数据");
        }
        VehicleParkingLotSecondBO vehicleParkingLotSecondBO = vehicleParkingLotSecondBOList.get(0);

        QueryVehiclePayRecordStatisticsBO queryVehiclePayRecordStatisticsBO = new QueryVehiclePayRecordStatisticsBO();
        queryVehiclePayRecordStatisticsBO.setProjectId(projectId);
        queryVehiclePayRecordStatisticsBO.setParkId(vehicleParkingLotSecondBO.getParkId());
        queryVehiclePayRecordStatisticsBO.setDateFormatString("%Y-%m-%d %H");
        queryVehiclePayRecordStatisticsBO.setStartTime(AboutDateUtil.theSameDayHourOfDate(startTime, VehicleConstant.vehicleTimeZone));
        queryVehiclePayRecordStatisticsBO.setEndTime(AboutDateUtil.theSameDayHourOfDate(endTime, VehicleConstant.vehicleTimeZone));

        List<VehiclePayRecordStatisticsDatePO> vehiclePayRecordStatisticsDatePOList = vehiclePayRecordMapper.payRecordStatistics(queryVehiclePayRecordStatisticsBO);
        vehiclePayRecordStatisticsDatePOList.forEach(vehiclePayRecordStatisticsDatePO -> {
            log.info("pay---------");
            log.info("date: " + vehiclePayRecordStatisticsDatePO.getDate());
            log.info("count: " + vehiclePayRecordStatisticsDatePO.getCount());
        });

        List<VehicleInitPayRecordStatisticsBO> vehicleInitPayRecordStatisticsBOList = new ArrayList<>();
        for (Date start = startTime; start.before(endTime); start=AboutDateUtil.datePlusHour(start, 1)) {
            VehicleInitPayRecordStatisticsBO vehicleInitPayRecordStatisticsBO = new VehicleInitPayRecordStatisticsBO();
            vehicleInitPayRecordStatisticsBO.setDate(AboutDateUtil.dateToString(start, "yyyy-MM-dd HH"));
            vehicleInitPayRecordStatisticsBO.setTotal(0);
            vehicleInitPayRecordStatisticsBOList.add(vehicleInitPayRecordStatisticsBO);
        }
        vehicleInitPayRecordStatisticsBOList.forEach(vehicleInitPayRecordStatisticsBO -> {
            log.info("init pay record---------");
            log.info("date: " + vehicleInitPayRecordStatisticsBO.getDate());
        });

        vehiclePayRecordStatisticsDatePOList.forEach(vehiclePayRecordStatisticsDatePO -> {
            Optional<VehicleInitPayRecordStatisticsBO> optionalVehicleInitPayRecordStatisticsBO = vehicleInitPayRecordStatisticsBOList.stream()
                    .filter(vehicleInitPayRecordStatisticsBO -> vehicleInitPayRecordStatisticsBO.getDate().equals(vehiclePayRecordStatisticsDatePO.getDate()))
                    .findFirst();

            Optionals.ifPresentOrElse(optionalVehicleInitPayRecordStatisticsBO, vehicleInitPayRecordStatisticsBO -> {
                vehicleInitPayRecordStatisticsBO.setTotal(vehiclePayRecordStatisticsDatePO.getCount());
            }, () -> {
                log.info("在初始化的统计集合中找不到支付该时间:" + vehiclePayRecordStatisticsDatePO.getDate());
            });
        });

        biVehicleService.addDwsPayRecordForHours(vehicleInitConverter.toCreateBiVehiclePayRecordHourFeignDTOList(vehicleInitPayRecordStatisticsBOList, projectId, parkingLotName, processTime));

        return ResultJson.successWithResult("init statistics for pay record success!");
    }

}
